package com.goldgov.code.template.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.goldgov.code.meta.ModuleInfo;
import com.goldgov.code.template.Group;
import com.goldgov.code.template.Layout;
import com.goldgov.code.template.ParamKeyName;
import com.goldgov.code.template.point.CodePoint;
import com.goldgov.code.template.point.PointMapping;
import com.goldgov.code.template.point.impl.ImportCodePoint;
import com.goldgov.code.template.point.impl.MemberCodePoint;
import com.goldgov.code.template.point.impl.MethodBodyCodePoint;
import com.goldgov.code.utils.CodeUtils;
import com.goldgov.code.utils.PackageUtils;
import com.goldgov.code.utils.StringUtils;

public class WebLayout implements Layout{

	public static final String PACKAGE_NAME = "web";
	
	@Override
	public String packageName() {
		return PACKAGE_NAME;
	}

	@Override
	public String templatePath() {
		return PACKAGE_NAME;
	}

	@Override
	public Class<?>[] dependOn() {
		return new Class[] {BeanLayout.class};
	}

	@Override
	public PointMapping codePoint(String packageName,ModuleInfo moduleInfo,Group group,Map<String,Object> paramMap) {
		PointMapping pointMapping = new PointMapping();
		
		List<CodePoint> codePoint = pointMapping.codePoint("**/*.java.ftl");
		codePoint.add(new ImportCodePoint(PackageUtils.joinPackageName(packageName,moduleInfo.getPackageName(),BeanLayout.PACKAGE_NAME,moduleInfo.getName())));
		codePoint.add(new ImportCodePoint(PackageUtils.joinPackageName(packageName,moduleInfo.getPackageName(),BeanLayout.PACKAGE_NAME,moduleInfo.getName()+"Query")));
		codePoint.add(new ImportCodePoint("com.goldgov.kcloud.core.json.JsonObject"));
		codePoint.add(new ImportCodePoint("com.goldgov.kcloud.core.json.JsonSuccessObject"));
		codePoint.add(new ImportCodePoint("com.goldgov.kcloud.core.json.JsonQueryObject"));
		codePoint.add(new ImportCodePoint(Autowired.class));
		codePoint.add(new ImportCodePoint(RestController.class));
		codePoint.add(new ImportCodePoint(RequestParam.class));
		codePoint.add(new ImportCodePoint(RequestMapping.class));
		codePoint.add(new ImportCodePoint(PathVariable.class));
		codePoint.add(new ImportCodePoint(PostMapping.class));
		codePoint.add(new ImportCodePoint(PutMapping.class));
		codePoint.add(new ImportCodePoint(GetMapping.class));
		codePoint.add(new ImportCodePoint(DeleteMapping.class));
		codePoint.add(new ImportCodePoint(RequestHeader.class));
		
		
		Layout[] layouts = group.getLayouts();
		for(Layout l : layouts) {
			if(l instanceof ServiceLayout) {
				String serviceClass = PackageUtils.joinPackageName(packageName,moduleInfo.getPackageName(),BeanLayout.PACKAGE_NAME,moduleInfo.getName() + "Service");
				codePoint.add(new ImportCodePoint(serviceClass));
				MemberCodePoint memberCodePoint = new MemberCodePoint(moduleInfo.getName() + "Service " + StringUtils.lowerFirstChar(moduleInfo.getName())+"Service");
				memberCodePoint.setAnnotation(Autowired.class);
				codePoint.add(memberCodePoint);
				String addCodes = addCodes(moduleInfo);
				
				Map<String,Object> extParam = (Map<String, Object>) paramMap.get("extParam");
				boolean genDefField = Boolean.valueOf(""+extParam.get(ParamKeyName.GEN_DEFAULT_FIELD));
				if(genDefField) {
					codePoint.add(new ImportCodePoint(Date.class));
					String defValue = "";
					String varName = StringUtils.lowerFirstChar(moduleInfo.getName());
					defValue += varName + ".setCreateUser(userID);\r\n";
					defValue += CodeUtils.code(2, varName + ".setCreateDate(new Date());");
					defValue += CodeUtils.code(2, varName + ".setState(1);//FIXME 常量代替 CoreUtils.ACTIVE_YES ?");
					addCodes =  defValue + CodeUtils.indentSpace(2) + addCodes;
				}
				codePoint.add(new MethodBodyCodePoint("ADD",addCodes));
				codePoint.add(new MethodBodyCodePoint("UPDATE",updateCodes(moduleInfo)));
				codePoint.add(new MethodBodyCodePoint("DELETE",deleteCodes(moduleInfo)));
				codePoint.add(new MethodBodyCodePoint("GET",getCodes(moduleInfo)));
				codePoint.add(new MethodBodyCodePoint("LIST",listCodes(moduleInfo)));
			}
		}
		
		return pointMapping;
	}
	
	private String addCodes(ModuleInfo moduleInfo) {
		String varName = StringUtils.lowerFirstChar(moduleInfo.getName());
		return varName+"Service.add"+moduleInfo.getName()+"(" + varName + ");";
	}
	
	private String updateCodes(ModuleInfo moduleInfo) {
		String varName = StringUtils.lowerFirstChar(moduleInfo.getName());
		return varName+"Service.update"+moduleInfo.getName()+"(" + varName + ");";
	}
	
	private String deleteCodes(ModuleInfo moduleInfo) {
		return StringUtils.lowerFirstChar(moduleInfo.getName())+"Service.delete"+moduleInfo.getName()+"(ids);";
	}
	
	private String getCodes(ModuleInfo moduleInfo) {
		String varName = StringUtils.lowerFirstChar(moduleInfo.getName());
		String codes = moduleInfo.getName() + " " + varName + " = " + varName+"Service.get"+moduleInfo.getName()+"(" + varName + "ID);\r\n";
		codes += "        return new JsonSuccessObject<>(" + varName + ");";
		return  codes;
	}
	
	private String listCodes(ModuleInfo moduleInfo) {
		String codes = "List<" + moduleInfo.getName() + "> list = " + StringUtils.lowerFirstChar(moduleInfo.getName())+"Service.list"+moduleInfo.getName()+"(query);\r\n";
		codes += "        query.setResultList(list);\r\n";
		codes += "        return new JsonQueryObject<>(query);";
		return codes;
	}

	@Override
	public void init(ModuleInfo moduleInfo) {
		
	}

}
